<template>
  <div class="tableHeader">
    <div class="table-title">
      <span>{{ options.title }}</span>
    </div>
    <div class="table-option">
      <el-button type="primary" v-if="options.allowEdit" @click="handleCreate">
        新建
        <el-icon class="el-icon--right">
          <ElIconPlus/>
        </el-icon>
      </el-button>
      <el-button type="danger" v-if="options.allowDeleteMany" @click="handleDeleteMany">
        批量删除
        <el-icon class="el-icon--right">
          <ElIconDelete/>
        </el-icon>
      </el-button>
    </div>
  </div>
  <el-table :data="currData?.pageData" class="data-table"
            @selection-change="handleSelectionChange"
            @filter-change="handleFilterChange">
    <el-table-column type="selection" width="55" v-if="options.allowDeleteMany"/>
    <el-table-column v-for="col in tableCols" :key="col.columnName"
                     :prop="col.columnName"
                     :label="col.columnVerboseName"
                     :width="col.columnWidth"
                     :filters="getColumnFilter(col)"
                     :column-key="col.columnName">
      <template #default="scope">
        <div  v-html="getColumnData(scope, col)"></div>
      </template>
    </el-table-column>
    <el-table-column label="操作">
      <template #default="scope">
        <el-button type="primary" :icon="Edit" circle @click="handleEdit(scope.row)" v-if="options.allowEdit"/>
        <el-button type="danger" :icon="Delete" circle @click="handleDeleteOne(scope.row)" v-if="options.allowDelete"/>
      </template>
    </el-table-column>
  </el-table>
  <div v-if="options.allowEdit">
    <component :is="options.createDialog" :reload="reload" ref="createDialogRef"/>
    <component :is="options.updateDialog" :reload="reload" ref="updateDialogRef"/>
  </div>
  <div class="page-container">
    <el-pagination background layout="prev, pager, next" :total="props.data?.totalCount" :current-page="pageIndex"
                   @current-change="handlePageChange"/>
  </div>
</template>

<script setup lang="ts">

import {Edit, Delete} from '@element-plus/icons-vue'
import { render } from "@vue/runtime-dom";

const props = defineProps<{
  data: any,
  tableCols: Array<ElTableColumnSetting>,
  options: ElTableOptions,
}>();

const currData = ref(props.data);

watch(
    () => props.data,
    (val) => currData.value = val
)

const multipleSelected = ref([]);
const pageIndex = ref(currData.value?.pageIndex ?? 1);
const pageSize = ref(props.options.pageSize);
const createDialogRef = ref<InstanceType<typeof props.options.createDialog> | null>(null);
const updateDialogRef = ref<InstanceType<typeof props.options.updateDialog> | null>(null);
let filters: any = null;

/**
 * 监听表格选中信息
 * **/
const handleSelectionChange = (val: any) => {
  multipleSelected.value = val;
}

/**
 * 从配置中获取列的筛选信息
 * **/
const getColumnFilter = (col: ElTableColumnSetting) => {
  let filter = props.options.filterList.filter(x => x.columnName === col.columnName);
  if (filter?.length > 0) {
    return filter[0].filterValues;
  } else {
    return [];
  }
}


/**
 * 监听筛选选项的变化并执行筛选
 * **/
const handleFilterChange = (theFilters: any) => {
  filters = theFilters;
  reload();
}

/**
 * 从数据中获取对应列的数据并根据格式转换函数进行转换
 * **/
const getColumnData = (scope: any, col: ElTableColumnSetting) => {
  if(col.columnName.indexOf(".") < 0){
    return col.columnValueConverter(scope.row[col.columnName]);
  }else{
    let columnNames = col.columnName.split(".");
    let ret = scope.row;
    columnNames.forEach(name=>{
      ret = ret[name] ?? "";
    })
    return ret;
  }
}

/**
 * 重新加载数据
 * **/
const reload = () => {
  props.options.dataLoadFunc(pageIndex.value, pageSize.value, filters);
}

/**
 * 执行数据删除操作
 * **/
const handleDeleteOne = (row: any) => {
  ElMessageBox.confirm(
      '您确认执行删除操作吗?',
      '危险操作系统',
      {
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        type: 'warning',
      })
      .then(() => {
        props.options.deleteFunc(row.id);
      })
      .catch(() => {
        ElMessage({
          type: 'info',
          message: '操作已取消',
        })
      })
}

/**
 * 执行多数据删除操作
 * **/
const handleDeleteMany = () => {
  let ids = multipleSelected.value.map(x => x["id"]);
  if(ids.length === 0){
    ElMessageBox.alert("您没有选择任何数据！");
  }else{
    ElMessageBox.confirm(
        '您确认执行删除操作吗?',
        '危险操作提示',
        {
          confirmButtonText: '确认',
          cancelButtonText: '取消',
          type: 'warning',
        })
        .then(() => {
          props.options.deleteManyFunc(ids);
        })
        .catch(() => {
          ElMessage({
            type: 'info',
            message: '操作已取消',
          })
        })
  }
}


/**
 * 唤起数据修改弹出框组件，执行修改数据操作
 * **/
const handleEdit = (row: any) => {
  updateDialogRef.value.open(row);
}

/**
 * 换取数据新建弹出框组件，执行数据创建操作
 * **/
const handleCreate = () => {
  createDialogRef.value.open();
}

/**
 * 换页的时候执行的操作
 * **/
const handlePageChange = (page: number) => {
  pageIndex.value = page
  reload()
}


// 公开ref
defineExpose({createDialogRef, updateDialogRef, reload});

</script>

<style scoped>
.tableHeader {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.table-title span {
  font-size: 1.2em;
  font-weight: bold;
}

.page-container {
  height: 65px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.data-table {
  width: 100%;
  height: calc(100vh - 65px - 45px - 45px - 90px);
}
</style>